package com.ruoyi.project.file.gallery.service.impl;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hutool.core.lang.Dict;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.file.detail.domain.FileDetail;
import com.ruoyi.project.file.detail.service.IFileDetailService;
import com.ruoyi.project.file.gallery.controller.FileGalleryController;
import org.apache.commons.lang3.StringUtils;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.project.file.gallery.mapper.FileGalleryMapper;
import com.ruoyi.project.file.gallery.domain.FileGallery;
import com.ruoyi.project.file.gallery.service.IFileGalleryService;
import com.ruoyi.common.utils.text.Convert;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * 画廊记录Service业务层处理
 *
 * @author zhangqidi
 * @date 2025-08-07
 */
@Service
public class FileGalleryServiceImpl implements IFileGalleryService
{
    private static final Logger log = LoggerFactory.getLogger(FileGalleryServiceImpl.class);

    @Autowired
    private FileGalleryMapper fileGalleryMapper;
    @Autowired
    private FileStorageService fileStorageService;
    @Autowired
    private IFileDetailService fileDetailService;

    /**
     * 查询画廊记录
     *
     * @param id 画廊记录主键
     * @return 画廊记录
     */
    @Override
    public FileGallery selectFileGalleryById(String id)
    {
        return fileGalleryMapper.selectFileGalleryById(id);
    }

    /**
     * 查询画廊记录列表
     *
     * @param fileGallery 画廊记录
     * @return 画廊记录
     */
    @Override
    public List<FileGallery> selectFileGalleryList(FileGallery fileGallery)
    {
        return fileGalleryMapper.selectFileGalleryList(fileGallery);
    }

    /**
     * 新增画廊记录
     *
     * @param fileGallery 画廊记录
     * @return 结果
     */
    @Override
    public int insertFileGallery(FileGallery fileGallery)
    {
        fileGallery.setCreateTime(DateUtils.getNowDate());
        return fileGalleryMapper.insertFileGallery(fileGallery);
    }

    /**
     * 修改画廊记录
     *
     * @param fileGallery 画廊记录
     * @return 结果
     */
    @Override
    public int updateFileGallery(FileGallery fileGallery)
    {
//        fileGallery.setUpdateTime(DateUtils.getNowDate());
        return fileGalleryMapper.updateFileGallery(fileGallery);
    }

    /**
     * 批量删除画廊记录
     *
     * @param ids 需要删除的画廊记录主键
     * @return 结果
     */
    @Override
    public int deleteFileGalleryByIds(String ids)
    {
        return fileGalleryMapper.deleteFileGalleryByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除画廊记录信息
     *
     * @param id 画廊记录主键
     * @return 结果
     */
    @Override
    public int deleteFileGalleryById(String id)
    {
        return fileGalleryMapper.deleteFileGalleryById(id);
    }

    /**
     * 查询用户可见的画廊列表，支持模糊查詢
     *
     * @param fileGallery 画廊信息
     * @return 画廊列表
     */
    @Override
    public List<FileGallery> selectUserVisibleGalleryList(FileGallery fileGallery) {
        return fileGalleryMapper.selectUserVisibleGalleryList(fileGallery);
    }

    /**
     * 查询画廊文件
     *
     * @param galleryId 画廊ID
     * @param galleryType 画廊类型
     * @return 文件列表
     */
    @Override
    public List<FileDetail> selectGalleryFiles(String galleryId, Integer galleryType) {
        return fileGalleryMapper.selectGalleryFiles(galleryId, galleryType);
    }

    @Override
    public int countGalleryFiles(String galleryId, Integer galleryType) {
        return fileGalleryMapper.countGalleryFiles(galleryId, galleryType);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult saveMobileGallery(String title, String recordDate, String shareType, String content,
                                        Boolean isVideo, MultipartFile[] files, String currentUser) {
        try {
            // 1. 保存画廊信息到数据库
            FileGallery fileGallery = new FileGallery();
            fileGallery.setId(IdUtils.fastSimpleUUID());
            fileGallery.setCreateBy(currentUser);
            fileGallery.setTitle(title);
            fileGallery.setRecordDate(DateUtils.parseDate(recordDate));
            fileGallery.setContent(content);
            fileGallery.setShareType(Long.parseLong(shareType));
            Long galleryType = 1L;
            // 是否视频
            if (isVideo) {
                galleryType = 2L;
            }
            fileGallery.setGalleryType(galleryType);
            fileGallery.setGalleryStatus(1L);
            fileGallery.setIzDeleted(0L);
            this.insertFileGallery(fileGallery);

            // 2. 上传文件到存储系统 + 保存到数据库
            int currentYear = LocalDate.now().getYear();
            int orderNo = 1;
            for (MultipartFile file : files) {
                //上传文件到OSS，如果实现了FileRecorder结果，那么会调用save方法保存到数据库
                FileInfo fileInfo = fileStorageService.of(file)
                        .setPath(currentYear + "/") //保存到相对路径下，为了方便管理，不需要可以不写
                        .setObjectId(fileGallery.getId())   //关联对象id，为了方便管理，不需要可以不写
                        .setObjectType(galleryType + "") //关联对象类型，为了方便管理，不需要可以不写
                        .putAttr("order", orderNo) //图片顺序
                        .upload();  //将文件上传到对应地方
                orderNo++;
            }
            return AjaxResult.success();
        } catch (Exception e) {
            log.error("保存失败: ", e);
            throw new RuntimeException("保存失败: " + e.getMessage(), e);
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateMobileGallery(String id, String title, String recordDate, String shareType,
                                          String content, Boolean isVideo, MultipartFile[] files,
                                          String deletedFileIds, String fullSortedOrder, String currentUser) {
        try {
            if (isVideo == null) {
                isVideo = false;
            }
            // 1. 参数校验
            if (StringUtils.isAnyBlank(id, title, recordDate, shareType, fullSortedOrder)) {
                return AjaxResult.error("必要参数不能为空");
            }

            // 2. 查询画廊记录
            FileGallery gallery = fileGalleryMapper.selectFileGalleryById(id);
            if (gallery == null) {
                return AjaxResult.error("画廊不存在");
            }

            // 3. 权限检查（只有创建者可以更新）
            if (!currentUser.equals(gallery.getCreateBy())) {
                return AjaxResult.error("无权限更新该画廊");
            }

            // 4. 构造更新对象
            FileGallery updateGallery = new FileGallery();
            updateGallery.setId(id);
            updateGallery.setTitle(title);
            updateGallery.setRecordDate(DateUtils.parseDate(recordDate));
            updateGallery.setContent(content);
            updateGallery.setShareType(Long.parseLong(shareType));
            updateGallery.setUpdateBy(currentUser);
            updateGallery.setUpdateTime(DateUtils.getNowDate());

            // 5. 更新画廊基本信息
            int result = fileGalleryMapper.updateFileGallery(updateGallery);
            if (result <= 0) {
                return AjaxResult.error("更新画廊基本信息失败");
            }

            // 6. 处理文件删除
            if (StringUtils.isNotBlank(deletedFileIds)) {
                String[] fileIds = deletedFileIds.split(",");
                for (String fileId : fileIds) {
                    // 远程删除OSS云文件
                    FileDetail file = fileDetailService.selectFileDetailById(fileId);
                    if(file!= null && file.getUrl() != null){
                        fileStorageService.delete(file.getUrl());
                    }
                    // 删除关联的文件记录
                    fileDetailService.deleteFileDetailById(fileId);
                }
            }

            // 7. 处理新增文件
            String[] fullSortedItems = fullSortedOrder.split(",");
            List<Integer> newFileOrderList = new ArrayList<>();
            Map<String, Integer> oldFilesOrderMap = new HashMap<>();
            // 新增文件的排序。如果提供了完整排序信息，解析新文件在所有文件中的排序位置
            for (int i = 0; i < fullSortedItems.length; i++) {
                String item = fullSortedItems[i];
                // 新文件的tempId以"temp_"为前缀
                if (item.startsWith("temp_")) {
                    // 排序从1开始而不是0
                    newFileOrderList.add(i + 1);
                } else {
                    oldFilesOrderMap.put(item, i + 1);
                }
            }

            // 8. 文件保存
            if (files != null && files.length > 0) {
                // 与saveMobileGallery方法类似的文件上传逻辑
                int currentYear = LocalDate.now().getYear();
                for (int i = 0; i < files.length; i++) {
                    MultipartFile file = files[i];
                    // 如果提供了完整排序信息，则使用新的排序位置
                    int orderNo = 0;
                    if (newFileOrderList.size() > 0) {
                        orderNo = newFileOrderList.get(i);
                    }
                    // 上传文件到存储系统并保存到数据库
                    FileInfo fileInfo = fileStorageService.of(file)
                            .setPath(currentYear + "/")
                            .setObjectId(id)
                            .setObjectType((isVideo ? 2 : 1) + "")
                            .putAttr("order", orderNo)
                            .upload();
                }
            }

            // 9. 处理已有文件的排序
            if (!oldFilesOrderMap.isEmpty()) {
                for (String fileId : oldFilesOrderMap.keySet()) {
                    // 更新文件的排序序号
                    FileDetail fileDetail = fileDetailService.selectFileDetailById(fileId);
                    if (fileDetail != null) {
                        Dict attr = Dict.parse(JSONObject.parseObject(fileDetail.getAttr()));
                        attr.set("order", oldFilesOrderMap.get(fileId));
                        fileDetail.setAttr(JSON.toJSONString(attr));
                        fileDetailService.updateFileDetail(fileDetail);
                    }
                }
            }

            return AjaxResult.success("更新成功");
        } catch (Exception e) {
            log.error("更新画廊失败: ", e);
            throw new RuntimeException("更新画廊失败", e); // 重新抛出异常以触发事务回滚
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult deleteMobileGallery(String galleryId, String currentUser) {
        try {
            // 查询画廊记录
            FileGallery gallery = fileGalleryMapper.selectFileGalleryById(galleryId);
            if (gallery == null) {
                return AjaxResult.error("画廊不存在");
            }

            // 权限检查（只有创建者可以删除）
            if (!currentUser.equals(gallery.getCreateBy())) {
                return AjaxResult.error("无权限删除该画廊");
            }

            // 删除画廊记录
            int result = fileGalleryMapper.deleteFileGalleryById(galleryId);
            if (result > 0) {
                List<FileDetail> files = this.selectGalleryFiles(galleryId, null);
                // 远程删除OSS云文件
                for(FileDetail file : files){
                    if(file.getUrl() != null){
                        fileStorageService.delete(file.getUrl());
                    }
                }
                // 删除关联的文件记录
                fileDetailService.deleteFileDetailByObjectId(galleryId);
                return AjaxResult.success("删除成功");
            } else {
                return AjaxResult.error("删除失败");
            }
        } catch (Exception e) {
            log.error("删除画廊失败: ", e);
            throw new RuntimeException("删除画廊失败: " + e.getMessage(), e);
        }
    }

}
